package com.wyzt.item.service;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.wyzt.common.dto.CartDTO;
import com.wyzt.common.enums.ExceptionEnum;
import com.wyzt.common.exception.WyztException;
import com.wyzt.common.vo.PageResult;
import com.wyzt.item.bo.SpuBo;
import com.wyzt.item.mapper.SkuMapper;
import com.wyzt.item.mapper.SpuDetailMapper;
import com.wyzt.item.mapper.SpuMapper;
import com.wyzt.item.mapper.StockMapper;
import com.wyzt.item.pojo.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.amqp.AmqpException;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import tk.mybatis.mapper.entity.Example;

import java.util.*;
import java.util.stream.Collectors;

@Service
@Slf4j
public class GoodsService {
    @Autowired
    private SpuMapper spuMapper;
    @Autowired
    private SpuDetailMapper spuDetailMapper;
    @Autowired
    private SkuMapper skuMapper;
    @Autowired
    private StockMapper stockMapper;

    @Autowired
    private CategoryService categoryService;

    @Autowired
    private BrandService brandService;
    @Autowired
    private AmqpTemplate amqpTemplate;


    public PageResult<SpuBo> querySpuByPage(Integer page, Integer rows, Boolean saleable, String key) {
        //分页
        PageHelper.startPage(page, rows);
        //过滤
        Example example = new Example(Spu.class);
        Example.Criteria criteria = example.createCriteria();
        //搜索字段过滤
        if (StringUtils.isNotBlank(key)) {
            criteria.andLike("title", "%" + key + "%");
        }
        //上下架过滤
        if (saleable != null) {
            criteria.andEqualTo("saleable", saleable);
        }
        //默认排序
        example.setOrderByClause("last_update_time DESC");

        //查询
        Page<Spu> pageInfo = (Page<Spu>) spuMapper.selectByExample(example);
        List<Spu> spus = pageInfo.getResult();
        List<SpuBo> spuBos = new ArrayList<>();
        //判断
        if (CollectionUtils.isEmpty(spus)) {
            throw new WyztException(ExceptionEnum.GOODS_NOT_FOUND);
        }
        //解析分类和品牌的名称
        for (Spu spu : spus) {
            //处理分类名称
            List<String> names = categoryService.queryByIds(Arrays.asList(spu.getCid1(), spu.getCid2(), spu.getCid3()))
                    .stream().map(Category::getName).collect(Collectors.toList());
            SpuBo spuBo = new SpuBo();
            spuBo.setCname(StringUtils.join(names, "/"));
            //处理品牌名称
            spuBo.setBname(brandService.queryById(spu.getBrandId()).getName());
            BeanUtils.copyProperties(spu, spuBo);
            spuBos.add(spuBo);
        }

        PageResult<SpuBo> pageResult = new PageResult<>();
        pageResult.setTotal(pageInfo.getTotal());
        pageResult.setItems(spuBos);
        return pageResult;
    }

    @Transactional
    public void saveGoods(SpuBo spubo) {
        //新增spu
        Spu spu = new Spu();
        BeanUtils.copyProperties(spubo, spu);
        spu.setSaleable(true);
        spu.setValid(true);
        spu.setCreateTime(new Date());
        spu.setLastUpdateTime(spu.getCreateTime());

        int count = spuMapper.insert(spu);
        if (count != 1) {
            throw new WyztException(ExceptionEnum.GOODS_SAVE_ERROR);
        }
        //新增detail
        SpuDetail spuDetail = spubo.getSpuDetail();
        spuDetail.setSpuId(spu.getId());
        spuDetailMapper.insert(spuDetail);
        //新增sku
        List<Sku> skus = spubo.getSkus();
        //定义库存集合
        List<Stock> stocks = new ArrayList<>();
        for (Sku sku : skus) {
            sku.setCreateTime(new Date());
            sku.setLastUpdateTime(spu.getCreateTime());
            sku.setSpuId(spu.getId());
            count = skuMapper.insert(sku);
            if (count != 1) {
                throw new WyztException(ExceptionEnum.GOODS_SAVE_ERROR);
            }

            //新增stock
            Stock stock = new Stock();
            stock.setSkuId(sku.getId());
            stock.setStock(sku.getStock());
//            stocks.add(stock);
            stockMapper.insert(stock);
        }
        //批量新增库存
//        stockMapper.insertList(stocks);

        // TODO: 2018/12/11 发送mq消息
        try {
            amqpTemplate.convertAndSend("item.insert", spu.getId());
        } catch (AmqpException e) {
            log.error("insert 商品消息发送异常，商品id：{}", spu.getId(), e);
        }
    }

    public SpuDetail querySpuDetailById(Long id) {
        SpuDetail spuDetail = spuDetailMapper.selectByPrimaryKey(id);
        if (spuDetail == null) {
            throw new WyztException(ExceptionEnum.GOODS_DETAILS_NOT_FOUND);
        }
        return spuDetail;
    }

    public List<Sku> querySkuListById(Long id) {
        //查询sku
        Sku sku = new Sku();
        sku.setSpuId(id);
        List<Sku> skus = skuMapper.select(sku);
        if (CollectionUtils.isEmpty(skus)) {
            throw new WyztException(ExceptionEnum.GOODS_SKU_NOT_FOUND);
        }

        //查询库存---旧方法
//        for (Sku s : skus) {
//            Stock stock = stockMapper.selectByPrimaryKey(s.getId());
//            if (stock == null) {
//                throw new WyztException(ExceptionEnum.GOODS_STOCK_NOT_FOUND);
//            }
//            s.setStock(stock.getStock());
//        }

        //查询库存----jdk8方法
        List<Long> ids = skus.stream().map(Sku::getId).collect(Collectors.toList());
        List<Stock> stocks = stockMapper.selectByIdList(ids);
        if (CollectionUtils.isEmpty(stocks)) {
            throw new WyztException(ExceptionEnum.GOODS_STOCK_NOT_FOUND);
        }
        //把stock对象变成一个map，key是sku的id，value是库存值
        Map<Long, Long> stockMap
                = stocks.stream().collect(Collectors.toMap(Stock::getSkuId, Stock::getStock));
        skus.forEach(s -> s.setStock(stockMap.get(s.getId())));

        return skus;
    }

    public Spu querySpuById(Long id) {
        //查询spu
        Spu spu = this.spuMapper.selectByPrimaryKey(id);
        if (spu == null) {
            throw new WyztException(ExceptionEnum.SPU_NOT_FOUND);
        }
        //
        return spu;
    }

    public SpuBo querySpuBoById(Long id) {
        //查询spu
        Spu spu = this.spuMapper.selectByPrimaryKey(id);
        if (spu == null) {
            throw new WyztException(ExceptionEnum.SPU_NOT_FOUND);
        }

        //处理分类名称
        List<String> names = categoryService.queryByIds(Arrays.asList(spu.getCid1(), spu.getCid2(), spu.getCid3()))
                .stream().map(Category::getName).collect(Collectors.toList());
        SpuBo spuBo = new SpuBo();
        spuBo.setCname(StringUtils.join(names, "/"));
        //处理品牌名称
        spuBo.setBname(brandService.queryById(spu.getBrandId()).getName());
        BeanUtils.copyProperties(spu, spuBo);

        return spuBo;
    }

    @Transactional
    public void decreaseStock(List<CartDTO> carts) {
        for (CartDTO cart : carts) {
            //减库存
            int count = stockMapper.decreaseStock(cart.getSkuId(), cart.getNum());
            if (count != 1) {
                throw new WyztException(ExceptionEnum.STOCK_NOT_ENOUGH);
            }
        }
    }
}
